#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>
#include <math.h>
#include <ctype.h>
#include <sys/time.h>
#include "rede.h"
#include "alggen.h"



int main(int argc, char *argv[]){
	
	//matriz de rede(Rede) e matriz de recurso da rede(RNET)
	
	RNET ** rnet;
	int ** qtdRotas;
	Solucao * solucao;
	int numSolucoes;
	int melhorSolIni;
	int contador;//testes da lista 
	int teste,teste1=4;
	int i,cont,j,s,d,k,nw,sai=0,t; // variaveis copiadas do leandro que eu nao sei pra que funciona
	int n_links, convergiu;
	char *instancia;
	instancia = argv[1];
	

	//recebe as matrizes de trafego e adjacencia do arquivo
	LeMatriz(instancia);
	//alocando matriz de rede
	
	//rede[i][j].demanda sendo atribuido
	
	//imprimeDemanda(rede);
	//alocaRNET
	rnet=alocaMatrizRNET();
	//aloca o vetorSlotsZERADOS
	alocaVetorSlots(rnet);
	//converte o arquivo para funcoes do leandro	
	convertearquivo();
	//funcao do leandro para fazer as rotas
	ArqRotas();
	//le e analisa as rotas (leandro)
	lerEanalisar01();
	//imprime todas as rotas de uma demanda
   	mostratudo();
   	//exclui os arquivos usados para mexer na funcao
   	system("rm lixo");
	system("rm lixo2");	
	
	 //MATRIZ COM A QUANTIDADE DE ROTAS	
	 qtdRotas=alocaMatriz();
	 zeraMatriz(qtdRotas,n,n);
	 matrizQtdRotas(qtdRotas);
	 //imprimeMatriz(qtdRotas,n,n);
	 //ATE AQUI EH O BASICO, DE ALOCAR MATRIZES DE ESTRUTURAS E RECEBER INFORMACOES DO ARQUIVO COM A REDE
	
	
   	 n_links=descobreNumLinks();
    //	printf("Links: %d\n", n_links);
	 //AQUI EU FACO A LISTA DE DEMANDAS DA REDE QUE FOI PASSADA
	 Lista * l;
	 //No * nodo;
	 l=(Lista*)malloc(sizeof(Lista));
	 l->tam=0;
	 l=recebeRecurso(l);
	
	
	imprimeLista(l);
	
	 // AQUI EU CRIO UM VETOR DE SOLUCOES INICIAIS BASICAS
   	 numSolucoes=NUM_SOLUCOES;
	 solucao=alocaSolucao(numSolucoes);
	printf("NUmSOl: %d\n", numSolucoes);	
		
	
	 for(contador=0; contador<numSolucoes; contador++){
		
		  printf("\n\n\t\t\tSolucao %d \n\n\n", contador);
		  solucao[contador]=atribuiDemandaLista(l,qtdRotas, solucao[contador]); //essa funcao retorna solucao completa, mas nao aloca solucao
		 // imprimeRNET(solucao[contador].rnet, contador);
		  // solucao[contador].rotas=rede;
	 }
	
	
	
	//imprimeSolucao(solucao,numSolucoes);
	
	// // CALCULO DO FITNESS DAS SOLUCOES
	 for(i=0; i<numSolucoes; i++){
		 solucao[i].fitness=calculaFitness(solucao[i]);
		// //printf("FitnessSolucao[%d]:%d\n",i, solucao[i].fitness);
	 }
	 
	 SolutionList * solList;
	 SolutionList * reprodutores;
	 SolutionList * novaGeracao;
	 solList=alocaSolutionList();
	 reprodutores=alocaSolutionList();
	 novaGeracao=alocaSolutionList();
	 
	 // passando as solucoes do vetor para uma lista de solutionList...
	 for(i=0; i< numSolucoes; i++){
		 if(solucao[i].erros==0){
			// // printf("LOOP %d\n", i);
			 Node * solNode;
			 solNode=alocaNode(solucao[i]);
			 insereSolutionListOrdenado(solList,solNode);
		}
	 }
	// // printf("\n\n\nTAMANHO DA LISTA %d\n\n", solList->tam);
	 if(solList->tam==0){
		 printf("Nenhuma solucao inicial sem erros foi feita\n\n");
		 exit(1);
	 }
	 melhorSolIni=solList->ini->sol.fitness;
	 imprimeSolutionList(solList);
	 srand(time(NULL));
	 convergiu = 0;
	 printf("MELHOR SOL INI %d\n", melhorSolIni);
	 
	 for(i=0; i<100; i++){
	
		
		 printf("\nconvergiu: %d\n ", convergiu);
		 // TRATAR PROBLEMA DE TAMANHO DAS LISTAS, POIS SE NAO FICA ENORME 
		 reprodutores=selecionaReprodutores(solList);
		 if(reprodutores->tam<=1) 
		 {
			 printf("Apenas um reprodutor selecionado");
			 exit(1);
		 }
		 printf("reprodutores->tam: %d\n", reprodutores->tam);	
			
		 novaGeracao=crossOver(reprodutores, l, qtdRotas);
		 if(novaGeracao->tam==0) continue;
		 novaGeracao=melhoresNovaGeracao(novaGeracao);
		
		// printf("PASSOU\n");
		 mutacaoSolutionList(l, qtdRotas, novaGeracao); //so substitui se tiver zero erros.
		// printf("PASSOU2\n");
		 if(novaGeracao->ini->sol.fitness < melhorSolIni){
			convergiu++;
		 }
		 //else convergiu = 0;
		
		 solList=substituiPopulacao(solList, novaGeracao);
		
		 if(convergiu == 3) break;
		
	}	
	
	//printf("VALOR DE I: %d\n", i);
	imprimeSolutionList2(solList);
	
	// // LEMBRAR QUE ALTEREI FUNCAO DE CROSSOVER COM FUNCAO DE COMPARACAO DE MATRIZ
	
	
	
   	return 0;
   }
